#pragma once
#include "ncti_base.h"
#include "dcl_ncti_object.h"
#include "NctiPosition.h"
#include <cmath>
#include "vector"

namespace NCTI
{
    class NctiMeshBody;
    class DECL_NCTI_OBJECT NctiDisplayGridMeshPub
    {
    public:
        NctiDisplayGridMeshPub(NctiMeshBody*);

        struct Vector3 {
            double x, y, z;
            Vector3(double i_x, double i_y, double i_z)
            {
                x = i_x;
                y = i_y;
                z = i_z;
            }
            // 计算向量的模长
            double magnitude() const {
                return sqrt(x * x + y * y + z * z);
            }

            // 计算两个向量的点积
            double dot(const Vector3& other) const {
                return x * other.x + y * other.y + z * other.z;
            }

            // 计算向量叉乘
            Vector3 crossProduct(const Vector3& other) {
                return { y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x };
            }

            Vector3 operator-(const Vector3& other)
            {
                return Vector3(x - other.x, y - other.y, z - other.z);
            }
        };

        //网格质量检查-网格颜色分类显示
        void ShowMeshClassifyColor( const std::vector<Ncti_UInteger>& i_allElements, const std::vector<double>& i_ValueVec);

        //nMode 0长宽比 1扭曲度 2雅克比 3最小角度 4最大角度 
        void GetMeshValue(Ncti_Integer nMode, std::vector<Ncti_UInteger>& o_allElements, std::vector<double>& o_ValueVec);


        std::vector<std::string> GetMeshShowText(Ncti_Integer nMode, const std::vector<Ncti_UInteger>& i_allElements);

        //*************网格质量检查**********
        double GetInnerAngle(NctiPosition pt1, NctiPosition pt2, NctiPosition pt3); //获取夹角(pt2为夹角点)
        double calculateJacobianDeterminant(NctiElementType mType, const std::vector<NctiPosition>& posVec); //计算雅克比

        //一下是各种单元计算雅克比的接口
        double determinant33(const std::vector<std::vector<double>>& matrix); // 定义一个函数来计算3x3矩阵的行列式
        double jacobianRatio_Triangle3(const std::vector<std::vector<double>>& vertices);//三角形
        double jacobianRatio_Quadrangle4(const std::vector<std::vector<double>>& vertices); //四边形
        double jacobianDeterminant_Tetrahedron4(const std::vector<std::vector<double>>& vertices, int i, int j, int k);
        double jacobianRatio_Tetrahedron4(const std::vector<std::vector<double>>& vertices);
        double jacobianRatio_Tetrahedron4(std::vector<Vector3>& vertices);//(四面体) 第二种方法
        double jacobianDeterminant_Hexahedron8(const std::vector<std::vector<double>>& vertices, double xi, double eta, double zeta);
        double jacobianRatio_Hexahedron8(const std::vector<std::vector<double>>& vertices);
        double jacobianRatio_Hexahedron8(std::vector<Vector3>& vertices); //(六面体)第二种方法
        double jacobianDeterminant_Prism6(const std::vector<std::vector<double>>& vertices, double xi, double eta, double zeta);
        double jacobianRatio_Prism6(const std::vector<std::vector<double>>& vertices);
        double jacobianRatio_Prism6(std::vector<Vector3>& vertices);//(棱柱)第二种方法
        double jacobianRatio_Pyramid5(std::vector<Vector3>& vertices);  //金字塔

        void GetMeshAspectRatio(std::vector<Ncti_UInteger>& o_allElements, std::vector<double>& o_ValueVec); //长宽比
        void GetDistortionDegree(std::vector<Ncti_UInteger>& o_allElements, std::vector<double>& o_ValueVec); //扭曲度

        void GetJacobi(std::vector<Ncti_UInteger>& o_allElements, std::vector<double>& o_ValueVec);  // 雅克比
        void GetMinAngle(std::vector<Ncti_UInteger>& o_allElements, std::vector<double>& o_ValueVec);  //最小角度
        void GetMaxAngle(std::vector<Ncti_UInteger>& o_allElements, std::vector<double>& o_ValueVec);  //最大角度


    private:
        NctiMeshBody* m_part{ nullptr };//no save
    };
}

